
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace LightScribe
{
	public class PrintSession : IDisposable
	{
		private IntPtr printer;
		private IntPtr session;
		private Image image = null;
		private PrintCallbacks callbacks;
		public event AbortLabelDelegate AbortLabel;
		public event ReportPrepareProgressDelegate ReportPrepareProgress;
		public event ReportLabelProgressDelegate ReportLabelProgress;
		public event ReportFinishedDelegate ReportFinished;
		public event ReportLabelTimeEstimateDelegate ReportLabelTimeEstimate;
		internal PrintSession(IntPtr printer)
		{
			Interop.DiscPrinter_OpenPrintSession(this.printer = printer, out session);
			callbacks = new PrintCallbacks();
			callbacks.AbortLabel = AbortLabelCallback;
			callbacks.ReportFinished = ReportFinishedCallback;
			callbacks.ReportLabelProgress = ReportLabelProgressCallback;
			callbacks.ReportLabelTimeEstimate = ReportLabelTimeEstimateCallback;
			callbacks.ReportPrepareProgress = ReportPrepareProgressCallback;
			Error e = Interop.DiscPrintSession_SetProgressCallback(session, ref callbacks);
			Console.WriteLine(e);
			//Interop.print, preview, progress, save
		}
		
		public Image Image
		{
			get
			{
				return image;
			}
			set
			{
				image = value;
			}
		}
		
		public void Preview(string path)
		{
			using (MemoryStream stream = new MemoryStream())
			{
				Image.Save(stream, ImageFormat.Bmp);
				byte[] data = stream.ToArray();
				byte[] header = new byte[40];
				Buffer.BlockCopy(data, 14, header, 0, 40);
				byte[] temp = new byte[data.Length - 40 - 14];
				Buffer.BlockCopy(data, 40 + 14, temp, 0, temp.Length);
				data = temp;
				Error e = Interop.DiscPrintSession_PrintPreview(session, ImageType.WindowsBitmap, LabelMode.Full,
				                                      DrawOptions.FitSmallestToLabel, PrintQuality.Best,
				                                      MediaOptimizationLevel.Recognized, header, header.Length,
				                                      data, data.Length, path, ImageType.WindowsBitmap,
				                                      new LightScribe.Size(600, 600), false);
				//Console.WriteLine("Return from preview: {0}", e);
			}
		}
			
		private bool AbortLabelCallback()
		{
			if (AbortLabel != null)
				return AbortLabel();
			return false;
		}
		
		private void ReportPrepareProgressCallback(int current, int final)
		{
			if (ReportPrepareProgress != null)
				ReportPrepareProgress(current, final);
		}
		
		private void ReportLabelProgressCallback(int current, int final)
		{
			if (ReportLabelProgress != null)
				ReportLabelProgress(current, final);
		}
		
		private void ReportFinishedCallback(Error status)
		{
			if (ReportFinished != null)
				ReportFinished(status);
		}
		
		private bool ReportLabelTimeEstimateCallback(int time)
		{
			if (ReportLabelTimeEstimate != null)
				return ReportLabelTimeEstimate(time);
			return false;
			
		}
		
		public void Dispose()
		{
			Interop.DiscPrintSession_Destroy(ref session);
		}
	}
}
